using M13.Base;
using M13.GameSystem;
using QFramework;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
using Cysharp.Threading.Tasks;
using UnityEngine.SceneManagement;
using M13.Game.World;

namespace M13.Game.UI
{
    [RequireComponent(typeof(MainMenuUI))]
    public class MainMenu : MonoBehaviour, IController,ICanSendEvent//��֣�9
    {
        MainMenuUI _mainMenuUI;
        ISaveSystem _saveSystem;
        [SerializeField] private string saveName;
        [SerializeField] private int saveSeed;
        string _savePath;
        [SerializeField] private List<GameObject> savePageLists = new List<GameObject>();
        [SerializeField] private List<SaveConfig> saveConfigList = new List<SaveConfig>();
        private void Start()
        {
            _savePath = Application.persistentDataPath + "/save";
            _saveSystem = this.GetSystem<ISaveSystem>();
            _mainMenuUI = GetComponent<MainMenuUI>();
            this.RegisterEvent<StartGameButtonOfMainMenu>(e => { MainMenuToSaveListMenu(); RefreshSaveLists(); });
            this.RegisterEvent<OptionButtonOfMainMenu>(e => { });
            this.RegisterEvent<ExitButtionOfMainMenu>(e => ExitFromGame());

            this.RegisterEvent<SearchBoxValueChanged>(e => FilterSaveSearched());
            this.RegisterEvent<ExitFromSaveMenuButton>(e => SaveListMenuToMainMenu());
            this.RegisterEvent<RefreshSaveListsButton>(e => RefreshSaveLists());
            this.RegisterEvent<IntoWorldCreationMenuButton>(e => SaveListMenuToCreateWorldMenu());

            this.RegisterEvent<DeleteSaveButton>((e) => DeleteSaveRequest(e.saveConfig));

            this.RegisterEvent<ConfirmDeleteSaveButton>((e) => { });//Ӧ���ɴ浵ϵͳע����¼��������¼�ɾ���浵�ļ�
            this.RegisterEvent<CancelDeleteSaveButton>((e) => { });

            this.RegisterEvent<ExitFormWorldCreationMenuButton>((e) => CreateWorldMenuToSaveListMenu());
            this.RegisterEvent<CreateNewSaveButton>((e) => CreateSave());
            this.RegisterEvent<SaveNameInputChanged>((e) => SetSaveName());
            this.RegisterEvent<SaveSeedInputChanged>((e) => SetSaveSeed());

            this.RegisterEvent<CreateWorld>(e => CreateWorldMenuToCreateProgress());
            this.RegisterEvent<CreateWorldFinished>(e => CreateProgressToSaveListMenu());

            this.RegisterEvent<IntoWorldButton>(e =>
            {
                IntoWorld intoWorld;
                intoWorld.saveConfig = e.saveConfig;
                this.SendEvent(intoWorld);
            });
        }

        private void CreateSave()
        {
            SetSaveName();
            SetSaveSeed();
            SaveConfig saveConfig = new SaveConfig();
            AddSavePage(true,ref saveConfig);
            Debug.Log(saveConfig.name + ";" + saveConfig.seed + ";" + saveConfig.saveId + ";" + saveConfig.time);
            _mainMenuUI.ClearInput();
            CreateWorldMenuToSaveListMenu();

            _saveSystem.CreateNewSaveDirectory(saveConfig);
        }

        private void AddSavePage(bool isNew, ref SaveConfig saveConfig)
        {
            GameObject savePage = _mainMenuUI.AddNewSavePage();
            savePage.transform.parent = _mainMenuUI.GetSaveListsParent().transform;

            Button intoSavePageButton = savePage.GetComponent<Button>();
            Button deleteButton = savePage.transform.GetChild(3).GetComponent<Button>();


            //���浵�б�������Ϣ
            if (isNew)
            {
                SavePageInfoFromNew(ref savePage, ref saveConfig);
                saveConfigList.Add(saveConfig);
                CreateWorld createWorld;
                createWorld.saveConfig = saveConfig;
                this.SendEvent(createWorld);
            }
            else
            {
                SavePageInfoFromLocal(ref savePage, saveConfig);
            }

            savePageLists.Add(savePage);
            

            //��ע�ᰴť�¼�
            SaveConfig sc = saveConfig;
            intoSavePageButton.onClick.AddListener(() => DoubleClick(sc));

            DeleteSaveButton deleteSaveButton;
            deleteSaveButton.saveConfig = saveConfig;
            deleteButton.onClick.AddListener(() => { this.SendEvent(deleteSaveButton); });
        }
        int _clickNum = 0;
        private async void DoubleClick(SaveConfig saveConfig)
        {
            _clickNum++;
            if(_clickNum == 2)
            {
                IntoWorldButton intoSaveButton;
                intoSaveButton.saveConfig = saveConfig;
                this.SendEvent(intoSaveButton);
            }
            await UniTask.WaitForSeconds(0.5f);
            _clickNum = 0;
            return;
        }

        private void SavePageInfoFromNew(ref GameObject savePage, ref SaveConfig saveConfig)
        {
            Text saveNameText = savePage.transform.GetChild(0).GetComponent<Text>();
            Text saveTime = savePage.transform.GetChild(1).GetComponent<Text>();

            saveConfig.name = saveName;
            SaveNameSetting(ref saveConfig);
            saveNameText.text = savePage.name = saveConfig.name;
            saveConfig.seed = saveSeed;
            saveConfig.time = saveTime.text = DateTime.Now.ToString();
            saveConfig.saveId = savePage.GetHashCode();

            Debug.Log(saveConfig.name + ";" + saveConfig.seed + ";" + saveConfig.saveId + ";" + saveConfig.time);
        }

        private void SavePageInfoFromLocal(ref GameObject savePage, SaveConfig saveConfig)
        {
            Text saveNameText = savePage.transform.GetChild(0).GetComponent<Text>();
            Text saveTime = savePage.transform.GetChild(1).GetComponent<Text>();
            savePage.name = saveNameText.text = saveConfig.name;
            saveTime.text = saveConfig.time;

        }
        
        /// <summary>
        /// ɾ������浵����
        /// </summary>
        /// <param name="saveConfig"></param>
        private void DeleteSaveRequest(SaveConfig saveConfig)
        {
            _mainMenuUI.SetSaveDeleteRequestBoxActivity(true);
            GameObject requestBox = _mainMenuUI.GetDeleteRequestBox();
            _mainMenuUI.GetRequestConfirmBtn().onClick.AddListener(() =>
            {
                _mainMenuUI.SetSaveDeleteRequestBoxActivity(false);
                saveConfigList.Remove(saveConfig);
                DestroySavePage(saveConfig);
                _mainMenuUI.GetRequestCancelBtn().onClick.RemoveAllListeners();
                _mainMenuUI.GetRequestConfirmBtn().onClick.RemoveAllListeners();

                ConfirmDeleteSaveButton confirmDeleteSaveButton;
                confirmDeleteSaveButton.saveName = saveConfig.name;
                this.SendEvent<ConfirmDeleteSaveButton>();

                _saveSystem.DeleteSave(saveConfig.name);
                

            });
            _mainMenuUI.GetRequestCancelBtn().onClick.AddListener(() =>
            {
                _mainMenuUI.SetSaveDeleteRequestBoxActivity(false);
                _mainMenuUI.GetRequestCancelBtn().onClick.RemoveAllListeners();
                _mainMenuUI.GetRequestConfirmBtn().onClick.RemoveAllListeners();
            });
        }

        private void DestroySavePage(SaveConfig saveConfig)
        {
            for (int i = 0; i < savePageLists.Count; i++)
            {
                if (savePageLists[i].name == saveConfig.name)
                {
                    Destroy(savePageLists[i]);
                    savePageLists.RemoveAt(i);
                    break;
                }
            }
        }


        private void SetSaveName()
        {
            saveName = _mainMenuUI.GetSaveNameInput().text;
        }

        private void SetSaveSeed()
        {
            string strSeed = _mainMenuUI.GetSaveSeedInput().text;
            if (strSeed.Length != 0)
            {
                if (Convert.ToInt64(strSeed) > int.MaxValue || Convert.ToInt64(strSeed) < int.MinValue) saveSeed = Random.Range(int.MinValue, int.MaxValue);
                else saveSeed = Convert.ToInt32(strSeed);
            }
            else saveSeed = 0;
        }

        /// <summary>
        /// ��Ҫ����浵ϵͳ
        /// </summary>
        public void RefreshSaveLists()
        {
            for(int i = 0; i < saveConfigList.Count; i++)
            {
                DestroySavePage(saveConfigList[i]);
            }
            saveConfigList.Clear();
            saveConfigList = _saveSystem.TraverseFolders(_savePath);
            for(int i = 0; i < saveConfigList.Count; i++)
            {
                var sc = saveConfigList[i];
                AddSavePage(false,ref sc);
            }
        }

        public void FilterSaveSearched()
        {
           string inputTest =  _mainMenuUI.GetSaveSearchBox().text;
            foreach (var save in savePageLists)
            {
                if (save.name.Contains(inputTest) || string.IsNullOrEmpty(inputTest)) save.SetActive(true);
                else save.SetActive(false);
            }
        }

        private void MainMenuToSaveListMenu()
        {
            _mainMenuUI.SetMainMenuActivity(false);
            _mainMenuUI.SetSaveListMenuActivity(true);
        }

        private void SaveListMenuToMainMenu()
        {
            _mainMenuUI.SetMainMenuActivity(true);
            _mainMenuUI.SetSaveListMenuActivity(false);
        }

        private void SaveListMenuToCreateWorldMenu()
        {
            _mainMenuUI.SetSaveListMenuActivity(false);
            _mainMenuUI.SetCreateWorldMenuActivity(true);
        }

        private void CreateWorldMenuToSaveListMenu()
        {
            _mainMenuUI.SetSaveListMenuActivity(true);
            _mainMenuUI.SetCreateWorldMenuActivity(false);
        }

        private void CreateWorldMenuToCreateProgress()
        {
            _mainMenuUI.SetWorldCreateProgressActivity(true);
            _mainMenuUI.SetSaveListMenuActivity(false);
        }

        private void CreateProgressToSaveListMenu()
        {
            _mainMenuUI.SetWorldCreateProgressActivity(false);
            _mainMenuUI.SetSaveListMenuActivity(true);
        }

        private void ExitFromGame()
        {
#if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
#else
            Application.Quit();
#endif
        }

        private void SaveNameSetting(ref SaveConfig saveConfig)
        {
            if (saveConfig.name.Length == 0 || saveConfig.name == null)
            {
                saveConfig.name = "�µ�����";

            }
            for (int i = 0; i < saveConfigList.Count; i++)
            {
                if (saveConfig.name == saveConfigList[i].name)
                {
                    saveConfig.name = IncrementSuffixNumber(saveConfigList[i].name);
                    i = -1;
                }
            }
        }

        private string IncrementSuffixNumber(string inputString)
        {
            if (inputString.EndsWith(")"))
            {
                int suffixStartIndex = inputString.LastIndexOf('(');
                if (suffixStartIndex != -1)
                {

                    string suffix = inputString.Substring(suffixStartIndex + 1, inputString.Length - suffixStartIndex - 2);
                    if (int.TryParse(suffix, out int number))
                    {
                        number++;
                        string newSuffix = $"({number})";
                        return inputString.Substring(0, suffixStartIndex) + newSuffix;
                    }
                    else inputString += "(1)";
                }
                else inputString += "(1)";
            }
            else inputString += "(1)";
            return inputString;
        }

        public IArchitecture GetArchitecture()
        {
            return GameArchitecture.Interface;
        }
    }
    
}